﻿using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace TemplateEngineWithChart.Docx.Processors.ProcessResults
{
    internal class LevelPrototype
    {
        private readonly ProcessContext _context;
        public bool IsValid { get; private set; }
        public LevelPrototype(ProcessContext context, IEnumerable<XElement> prototypeItems, IEnumerable<string> fieldNames)
        {
            _context = context;
            var currentLevelPrototype = new List<XElement>();

            // Items for which no content control.
            // Add this items to the prototype if there are items after them.
            var maybeNeedToAdd = new List<XElement>();
            var numberingElementReached = false;

            foreach (var prototypeItem in prototypeItems)
            {
                //search for first item with numbering
                if (!numberingElementReached)
                {
                    var paragraph = prototypeItem.DescendantsAndSelf(W.p).FirstOrDefault();
                    if (paragraph != null &&
                        ListItemRetriever.RetrieveListItem(
                        context.Document.NumberingPart, context.Document.StylesPart, paragraph)
                        .IsListItem)
                        numberingElementReached = true;
                    else
                        continue;
                }
                if ((!prototypeItem.FirstLevelDescendantsAndSelf(W.sdt).Any() && prototypeItem.Value != "") ||
                    (prototypeItem
                    .FirstLevelDescendantsAndSelf(W.sdt)
                    .Any(sdt => fieldNames.Contains(sdt.SdtTagName()))))
                {
                    currentLevelPrototype.AddRange(maybeNeedToAdd);
                    currentLevelPrototype.Add(prototypeItem);
                }

                else
                {
                    maybeNeedToAdd.Add(prototypeItem);
                }
            }
            if (!currentLevelPrototype.Any()) return;

            PrototypeItems = currentLevelPrototype;

            //if (fieldNames.Any(fn => !SdtTags.Contains(fn)))
            //{
            //    IsValid = false;
            //    return;
            //}

            IsValid = true;
            PrototypeItems = currentLevelPrototype;

        }

        private LevelPrototype(ProcessContext context, IEnumerable<XElement> prototypeItems)
        {
            _context = context;
            PrototypeItems = prototypeItems.ToList();
        }
        public List<XElement> PrototypeItems { get; private set; }

        private List<string> SdtTags
        {
            get
            {
                return PrototypeItems == null
                    ? new List<string>()
                    : PrototypeItems.DescendantsAndSelf(W.sdt)
                    .Select(sdt => sdt.SdtTagName())
                    .ToList();
            }
        }

        public LevelPrototype Clone()
        {
            return new LevelPrototype(_context, PrototypeItems.ToList());
        }
    }
}
